<?php

namespace App\Jobs;

use Throwable;
use App\Recharge\Library;
use App\Models\Mysql\XnTime;
use App\Models\Mysql\XnOrder;
use Illuminate\Bus\Queueable;
use App\Models\Admin\Supplier;
use App\Models\Mysql\XnMerchant;
use App\Models\Mysql\XnOrderBill;
use Illuminate\Support\Facades\Log;
use App\Models\Mysql\XnMerchantBill;
use App\Models\Mysql\XnSupplierGoods;
use Illuminate\Queue\SerializesModels;
use App\Recharge\Traits\RechargeTraits;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Jobs\Middleware\SupplierDbConnectCheck;


class Recharge implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, RechargeTraits;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(
        public Supplier $supplier,
        public array $order,
        public array $merchantBill,
        public array $orderBill,
        public XnSupplierGoods $goods,
        public array $info = []
    ){}

    /**
     * @return array
     */
    public function middleware(): array
    {
        return [new SupplierDbConnectCheck($this->supplier)];
    }

    /**
     * @return void
     * @throws Throwable
     */
    public function handle(): void
    {
        // 充值
        $this->supplier->connection()->transaction(function () {
            $now = time();
            [$year, $month] = explode('-', date('Y-m', $now));
            XnTime::s($this->supplier)->firstOrCreate(['year'=>$year,'month'=>$month,'type'=>$this->order['order_type']],['ctime'=>$now]);
            // 账单
            XnOrderBill::s($this->supplier)->create($this->orderBill);
            XnMerchantBill::s($this->supplier)->create($this->merchantBill);
            // 余额
            XnMerchant::s($this->supplier)->where('merchant_number', $this->order['merchant_number'])->increment('deduction_balance', $this->order['all_money']);
            /** @var XnOrder $order */
            $order = XnOrder::s($this->supplier)->create($this->order);
            // 入队
            Library::pushApiJob($this->supplier, $order);
        });
    }

    /**
     * 记录日志
     *
     * @param string $message
     * @param string $level
     * @param Throwable|null $e
     * @return bool
     */
    protected function log(string $message, string $level = 'info', ?Throwable $e = null): bool
    {
        Log::log($level, $message, [
            'supplier'      => $this->supplier->toArray(),
            'order'         => $this->order,
            'merchantBill'  => $this->merchantBill,
            'orderBill'     => $this->orderBill,
            'good'          => $this->goods->toArray(),
            'info'          => $this->info,
            'error'         => is_null($e) ? [] : error2array($e),
        ]);
        return true;
    }

}

